﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Xml.Serialization;
using RiskMan.DataClass.Models.Sterling;
using SterlingLib;

namespace RiskMan.DataClass
{
    public partial class Data
    {


        public ObservableCollection<SterlingItem> SterlingItemList = new ObservableCollection<SterlingItem>();
        public ObservableCollection<SterlingOrderModel> SterlingOrderItemList = new ObservableCollection<SterlingOrderModel>();
        public ObservableCollection<SterlingStockWatchModel> SterlingStockWatchItemList = new ObservableCollection<SterlingStockWatchModel>();
        public ObservableCollection<SterlingPositonModel> SterlingPositionItemList = new ObservableCollection<SterlingPositonModel>();
        public ObservableCollection<SterlingSymbol> SterlingSymbols = new ObservableCollection<SterlingSymbol>();
        public ObservableCollection<SterlingOrderTableItem> SterlingOrderTableItemList = new ObservableCollection<SterlingOrderTableItem>();
        public ObservableCollection<SterlingTradeTableItem> SterlingTradeTableItemList = new ObservableCollection<SterlingTradeTableItem>();
        
        #region Подключение к стерлингу

        public SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder();
        public SterlingLib.STIQuote stiQuote = new SterlingLib.STIQuote();
        private SterlingLib.STIApp stiApp = new SterlingLib.STIApp();
        public SterlingLib.STIPosition stiPosition = new SterlingLib.STIPosition();
        //public SterlingLib.STIOrderMaint stiOrderMaint = new STIOrderMaintClass();
        public SterlingLib.STIEvents stiEvents = new SterlingLib.STIEvents();

        #endregion


        public void SterlingStart()
        {

            stiApp.SetModeXML(true);
            stiQuote.OnSTIQuoteUpdateXML += new SterlingLib._ISTIQuoteEvents_OnSTIQuoteUpdateXMLEventHandler(OnSTIQuoteUpdateXML);
            stiQuote.OnSTIQuoteSnapXML += new SterlingLib._ISTIQuoteEvents_OnSTIQuoteSnapXMLEventHandler(OnSTIQuoteSnapXML);
            stiPosition.OnSTIPositionUpdateXML += new _ISTIPositionEvents_OnSTIPositionUpdateXMLEventHandler(OnSTIPositionUpdateXML);
            stiEvents.OnSTIOrderUpdateXML += new _ISTIEventsEvents_OnSTIOrderUpdateXMLEventHandler(OnSTIOrderUpdateXML);
            stiEvents.OnSTITradeUpdateXML += new _ISTIEventsEvents_OnSTITradeUpdateXMLEventHandler(OnSTITradeUpdateXML);
        }


        private void OnSTITradeUpdateXML(ref string strTrade)
        {
            XmlSerializer xs = new XmlSerializer(typeof(structSTITradeUpdate));
            SterlingLib.structSTITradeUpdate structTrade = (structSTITradeUpdate)xs.Deserialize(new StringReader(strTrade));
            if (!SterlingOrderTableItemList.Select(a => a.ClOrderId).ToList().Contains(structTrade.bstrExchOrderId))
            {
                Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
                    SterlingTradeTableItemList.Add(new SterlingTradeTableItem()
                    {
                        #region Добавление новой сдеки
                        Account = structTrade.bstrAccount,
                        Action = structTrade.bstrAction,
                        BatchId = structTrade.bstrBatchId,
                        ClOrderId = structTrade.bstrClOrderId,
                        Contra = structTrade.bstrContra,
                        CoverUncover = structTrade.bstrCoverUncover,
                        Destination = structTrade.bstrDestination,
                        ExchClOrderId = structTrade.bstrExchOrderId,
                        ExchOrderId = structTrade.bstrExchOrderId,
                        ExchOrderId2 = structTrade.bstrExchOrderId2,
                        ExecBroker = structTrade.bstrExecBroker,
                        ExecInst = structTrade.bstrExecInst,
                        Instrument = structTrade.bstrInstrument,
                        Liquidity = structTrade.bstrLiquidity,
                        LogMessage = structTrade.bstrLogMessage,
                        Maturity = structTrade.bstrMaturity,
                        OpenClose = structTrade.bstrOpenClose,
                        OrderTime = structTrade.bstrOrderTime,
                        PutCall = structTrade.bstrPutCall,
                        Side = structTrade.bstrSide,
                        Specialist = structTrade.bstrSpecialist,
                        Symbol = structTrade.bstrSymbol,
                        Tif = structTrade.bstrTif,
                        TradeTime = structTrade.bstrTradeTime,
                        Underlying = structTrade.bstrUnderlying,
                        UpdateTime = structTrade.bstrUpdateTime,
                        UserId = structTrade.bstrUserId,

                        Descretion = structTrade.fDiscretion,
                        ExecPrice = structTrade.fExecPrice,
                        LmtPrice = structTrade.fLmtPrice,
                        PegDiff = structTrade.fPegDiff,
                        StpPrice = structTrade.fStpPrice,
                        StrikePrice = structTrade.fStrikePrice,

                        DbsNo = structTrade.nDbsNo,
                        LvsQuantity = structTrade.nLvsQuantity,
                        OrderRecondId = structTrade.nOrderRecordId,
                        PriceType = structTrade.nPriceType,
                        Quantity = structTrade.nQuantity,
                        SeqNo = structTrade.nSeqNo,
                        TradeRecordId = structTrade.nTradeRecordId,

                        Clearable = structTrade.bClearable,
                        EcnFee = structTrade.bEcnFee
                        #endregion
                    }
                        )));
            }
            else
            {
                foreach (var item in SterlingTradeTableItemList)
                {
                    if (item.ClOrderId == structTrade.bstrExchOrderId)
                    {
                        #region Изменение параметров cделки

                        item.Account = structTrade.bstrAccount;
                        item.Action = structTrade.bstrAction;
                        item.BatchId = structTrade.bstrBatchId;
                        item.ClOrderId = structTrade.bstrClOrderId;
                        item.Contra = structTrade.bstrContra;
                        item.CoverUncover = structTrade.bstrCoverUncover;
                        item.Destination = structTrade.bstrDestination;
                        item.ExchClOrderId = structTrade.bstrExchOrderId;
                        item.ExchOrderId = structTrade.bstrExchOrderId;
                        item.ExchOrderId2 = structTrade.bstrExchOrderId2;
                        item.ExecBroker = structTrade.bstrExecBroker;
                        item.ExecInst = structTrade.bstrExecInst;
                        item.Instrument = structTrade.bstrInstrument;
                        item.Liquidity = structTrade.bstrLiquidity;
                        item.LogMessage = structTrade.bstrLogMessage;
                        item.Maturity = structTrade.bstrMaturity;
                        item.OpenClose = structTrade.bstrOpenClose;
                        item.OrderTime = structTrade.bstrOrderTime;
                        item.PutCall = structTrade.bstrPutCall;
                        item.Side = structTrade.bstrSide;
                        item.Specialist = structTrade.bstrSpecialist;
                        item.Symbol = structTrade.bstrSymbol;
                        item.Tif = structTrade.bstrTif;
                        item.TradeTime = structTrade.bstrTradeTime;
                        item.Underlying = structTrade.bstrUnderlying;
                        item.UpdateTime = structTrade.bstrUpdateTime;
                        item.UserId = structTrade.bstrUserId;

                        item.Descretion = structTrade.fDiscretion;
                        item.ExecPrice = structTrade.fExecPrice;
                        item.LmtPrice = structTrade.fLmtPrice;
                        item.PegDiff = structTrade.fPegDiff;
                        item.StpPrice = structTrade.fStpPrice;
                        item.StrikePrice = structTrade.fStrikePrice;

                        item.DbsNo = structTrade.nDbsNo;
                        item.LvsQuantity = structTrade.nLvsQuantity;
                        item.OrderRecondId = structTrade.nOrderRecordId;
                        item.PriceType = structTrade.nPriceType;
                        item.Quantity = structTrade.nQuantity;
                        item.SeqNo = structTrade.nSeqNo;
                        item.TradeRecordId = structTrade.nTradeRecordId;

                        item.Clearable = structTrade.bClearable;
                        item.EcnFee = structTrade.bEcnFee;

                        #endregion
                    }
                }
            }

        }

        private void OnSTIOrderUpdateXML(ref string strOrder)
        {
            XmlSerializer xs = new XmlSerializer(typeof(structSTIOrderUpdate));
            SterlingLib.structSTIOrderUpdate structOrder = (structSTIOrderUpdate)xs.Deserialize(new StringReader(strOrder));
            if (!SterlingOrderTableItemList.Select(a => a.ExchOrderId).ToList().Contains(structOrder.bstrExchOrderId))
            {
                Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
                    SterlingOrderTableItemList.Add(new SterlingOrderTableItem()
                    {
                        #region Добавление новой заявки
		Account = structOrder.bstrAccount,
                        Action = structOrder.bstrAction,
                        BatchId = structOrder.bstrBatchId,
                        ClOrderId = structOrder.bstrClOrderId,
                        CoverUncover = structOrder.bstrCoverUncover,
                        Destination = structOrder.bstrDestination,
                        ExchClOrderId = structOrder.bstrExchOrderId,
                        ExchClOrderId2 = structOrder.bstrExchOrderId2,
                        ExchOrderId = structOrder.bstrExchOrderId,
                        ExecBroker = structOrder.bstrExecBroker,
                        ExecInst = structOrder.bstrExecInst,
                        Instrument = structOrder.bstrInstrument,
                        LogMessage = structOrder.bstrLogMessage,
                        Maturity = structOrder.bstrMaturity,
                        OpenClose = structOrder.bstrOpenClose,
                        OrderTime = structOrder.bstrOrderTime,
                        PutCall = structOrder.bstrPutCall,
                        Side = structOrder.bstrSide,
                        Symbol = structOrder.bstrSymbol,
                        Tif = structOrder.bstrTif,
                        Underlying = structOrder.bstrUnderlying,
                        UpdateTime = structOrder.bstrUpdateTime,
                        User = structOrder.bstrUser,
                        UserId = structOrder.bstrUserId,

                        AvgExecPrice = structOrder.fAvgExecPrice,
                        Descretion = structOrder.fDiscretion,
                        LmtPrice = structOrder.fLmtPrice,
                        PegDiff = structOrder.fPegDiff,
                        StpPrice = structOrder.fStpPrice,
                        StrikePrice = structOrder.fStrikePrice,
                        TrailAmt = structOrder.fTrailAmt,
                        TrailInc = structOrder.fTrailInc,
                        UrStpdPrice = structOrder.fUrStpdPrice,

                        CumExecQuantity = structOrder.nCumExecQuantity,
                        DbsNo = structOrder.nDbsNo,
                        Display = structOrder.nDisplay,
                        LvsQuantity = structOrder.nLvsQuantity,
                        MinQuantity = structOrder.nMinQuantity,
                        OrderRecondId = structOrder.nOrderRecordId,
                        OrderStatus = structOrder.nOrderStatus,
                        PriceType = structOrder.nPriceType,
                        Quantity = structOrder.nQuantity,
                        SeqNo = structOrder.nSeqNo,
                        TrailId = structOrder.nTrailId,

                        SvrStpRelesed = structOrder.bSvrStpReleased 
	#endregion
                    }
                        )));
            }
            else
            {
                foreach (var item in SterlingOrderTableItemList)
                {
                    if (item.ExchOrderId == structOrder.bstrExchOrderId)
                    {
                        #region Изменение параметров заявки
		
                        item.Account = structOrder.bstrAccount;
                        item.Action = structOrder.bstrAction;
                        item.BatchId = structOrder.bstrBatchId;
                        item.ClOrderId = structOrder.bstrClOrderId;
                        item.CoverUncover = structOrder.bstrCoverUncover;
                        item.Destination = structOrder.bstrDestination;
                        item.ExchClOrderId = structOrder.bstrExchOrderId;
                        item.ExchClOrderId2 = structOrder.bstrExchOrderId2;
                        item.ExchOrderId = structOrder.bstrExchOrderId;
                        item.ExecBroker = structOrder.bstrExecBroker;
                        item.ExecInst = structOrder.bstrExecInst;
                        item.Instrument = structOrder.bstrInstrument;
                        item.LogMessage = structOrder.bstrLogMessage;
                        item.Maturity = structOrder.bstrMaturity;
                        item.OpenClose = structOrder.bstrOpenClose;
                        item.OrderTime = structOrder.bstrOrderTime;
                        item.PutCall = structOrder.bstrPutCall;
                        item.Side = structOrder.bstrSide;
                        item.Symbol = structOrder.bstrSymbol;
                        item.Tif = structOrder.bstrTif;
                        item.Underlying = structOrder.bstrUnderlying;
                        item.UpdateTime = structOrder.bstrUpdateTime;
                        item.User = structOrder.bstrUser;
                        item.UserId = structOrder.bstrUserId;

                        item.AvgExecPrice = structOrder.fAvgExecPrice;
                        item.Descretion = structOrder.fDiscretion;
                        item.LmtPrice = structOrder.fLmtPrice;
                        item.PegDiff = structOrder.fPegDiff;
                        item.StpPrice = structOrder.fStpPrice;
                        item.StrikePrice = structOrder.fStrikePrice;
                        item.TrailAmt = structOrder.fTrailAmt;
                        item.TrailInc = structOrder.fTrailInc;
                        item.UrStpdPrice = structOrder.fUrStpdPrice;

                        item.CumExecQuantity = structOrder.nCumExecQuantity;
                        item.DbsNo = structOrder.nDbsNo;
                        item.Display = structOrder.nDisplay;
                        item.LvsQuantity = structOrder.nLvsQuantity;
                        item.MinQuantity = structOrder.nMinQuantity;
                        item.OrderRecondId = structOrder.nOrderRecordId;
                        item.OrderStatus = structOrder.nOrderStatus;
                        item.PriceType = structOrder.nPriceType;
                        item.Quantity = structOrder.nQuantity;
                        item.SeqNo = structOrder.nSeqNo;
                        item.TrailId = structOrder.nTrailId;

                        item.SvrStpRelesed = structOrder.bSvrStpReleased; 
	#endregion
                    }
                }
            }

        }



        private void OnSTIQuoteSnapXML(ref string strQuote)
        {


            XmlSerializer xs = new XmlSerializer(typeof(structSTIQuoteSnap));
            structSTIQuoteSnap structQuote = (structSTIQuoteSnap)xs.Deserialize(new StringReader(strQuote));

            if (SterlingStockWatchItemList.Count == 0)
            {
                Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
                    SterlingStockWatchItemList.Add(
                        new SterlingStockWatchModel()
                        {
                            Symbol = structQuote.bstrSymbol,
                            LastPrice = structQuote.bLastPrice,
                            TradeCondition = structQuote.bstrTradeCondition


                        }
                        )));

            }

            if (SterlingStockWatchItemList.Count > 0)
            {
                if (!SterlingStockWatchItemList.Select(a => a.Symbol).ToList().Contains(structQuote.bstrSymbol))
                {

                    Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
                        SterlingStockWatchItemList.Add(new SterlingStockWatchModel()
                        {
                            Symbol = structQuote.bstrSymbol,
                            LastPrice = structQuote.bLastPrice,
                            TradeCondition = structQuote.bstrTradeCondition
                        }
                            )));


                }
            }
            //stiPosition.RegisterForPositions();
        }


        private void OnSTIQuoteUpdateXML(ref string strQuote)
        {
            XmlSerializer xs = new XmlSerializer(typeof(structSTIQuoteUpdate));
            SterlingLib.structSTIQuoteUpdate structQuote = (structSTIQuoteUpdate)xs.Deserialize(new StringReader(strQuote));
            foreach (var item in SterlingItemList)
            {
                if (item.Instrument == structQuote.bstrSymbol)
                    item.LastPrice = structQuote.fLastPrice;

            }
            foreach (var item in SterlingStockWatchItemList)
            {
                if (item.Symbol == structQuote.bstrSymbol)
                {
                    if (structQuote.fLastPrice > 0)
                        item.LastPrice = structQuote.fLastPrice;
                    item.TradeCondition = structQuote.bstrTradeCondition;
                }

            }

        }

        private void OnSTIPositionUpdateXML(ref string strPosition)
        {
            XmlSerializer xs = new XmlSerializer(typeof(structSTIPositionUpdate));
            SterlingLib.structSTIPositionUpdate structPosition = (structSTIPositionUpdate)xs.Deserialize(new StringReader(strPosition));
            foreach (var item in SterlingItemList)
            {
                if (item.Instrument == structPosition.bstrSym)
                    item.CurPosition = structPosition.nOpeningPosition + (structPosition.nSharesBot + structPosition.nSharesSld);

            }

            if (!SterlingPositionItemList.Select(a => a.Sym).Contains(structPosition.bstrSym))
                SterlingPositionItemList.Add(new SterlingPositonModel()
                {
                    Sym = structPosition.bstrSym,
                    Acct = structPosition.bstrAcct,
                    Instrument = structPosition.bstrInstrument,

                    OpeningPosition = structPosition.nOpeningPosition,
                    SharesBot = structPosition.nSharesBot,
                    SharesSld = structPosition.nSharesSld,
                    SharesSldLong = structPosition.nSharesSldLong,
                    SharesSldShort = structPosition.nSharesSldShort,

                    TicketsBot = structPosition.nTicketsBot,
                    TicketsSld = structPosition.nTicketsSld,
                    TicketsSldLong = structPosition.nTicketsSldLong,
                    TicketsSldShort = structPosition.nTicketsSldShort,

                    DollarsBot = structPosition.fDollarsBot,
                    DollarsSld = structPosition.fDollarsSld,
                    DollarsSldLong = structPosition.fDollarsSldLong,
                    DollarsSldShort = structPosition.fDollarsSldShort,

                    PositionCost = structPosition.fPositionCost,
                    PremiumMultiplier = structPosition.fPremiumMultiplier,
                    Real = structPosition.fReal,
                    SharesPerContract = structPosition.nSharesPerContract,

                    NPremiumMultiplier = structPosition.nPremiumMultiplier,
                    Last = structPosition.bLast,
                    MsgSnapShot = structPosition.bMsgSnapShot
                }
                    );

            if (SterlingPositionItemList.Count > 0)
                foreach (var item in SterlingPositionItemList)
                {
                    if (item.Sym == structPosition.bstrSym)
                    {
                        item.Sym = structPosition.bstrSym;
                        item.Acct = structPosition.bstrAcct;
                        item.Instrument = structPosition.bstrInstrument;

                        item.OpeningPosition = structPosition.nOpeningPosition;
                        item.SharesBot = structPosition.nSharesBot;
                        item.SharesSld = structPosition.nSharesSld;
                        item.SharesSldLong = structPosition.nSharesSldLong;
                        item.SharesSldShort = structPosition.nSharesSldShort;

                        item.TicketsBot = structPosition.nTicketsBot;
                        item.TicketsSld = structPosition.nTicketsSld;
                        item.TicketsSldLong = structPosition.nTicketsSldLong;
                        item.TicketsSldShort = structPosition.nTicketsSldShort;

                        item.DollarsBot = structPosition.fDollarsBot;
                        item.DollarsSld = structPosition.fDollarsSld;
                        item.DollarsSldLong = structPosition.fDollarsSldLong;
                        item.DollarsSldShort = structPosition.fDollarsSldShort;

                        item.PositionCost = structPosition.fPositionCost;
                        item.PremiumMultiplier = structPosition.fPremiumMultiplier;
                        item.Real = structPosition.fReal;
                        item.SharesPerContract = structPosition.nSharesPerContract;

                        item.NPremiumMultiplier = structPosition.nPremiumMultiplier;
                        item.Last = structPosition.bLast;
                        item.MsgSnapShot = structPosition.bMsgSnapShot;

                    }

                }

        }




        /// <summary>
        /// Словарь по ECN
        /// </summary>
        public Dictionary<char, string> DictionaryEcn = new Dictionary<char, string>()
        {
            {'A',"AMEX"},
            {'B',"NASDAQ OMX BX"},
            {'C',"National Stock Exchange"},
            {'D',"ADFN (FINRA)"},
            {'E',"Market Independent (Generated by SIP)"},
            {'I',"ISE (Alpha Quote Feed)"},
            {'J',"EDGA Exchange, Inc"},
            {'K',"EDGX Exchange, Inc"},
            {'M',"Chicago Stock Exchange (Midwest)"},
            {'N',"New York Stock Exchange"},
            {'P',"ARCA (NYSE ARCA)"},
            {'Q',"NASDAQ (NASDAQ listed symbols)"},
            {'T',"NASDAQ (Small Cap, Bulletin Board, and OTC)"},
            {'U',"OTC-BB"},
            {'W',"CBOE Stock Exchange (CBSX)"},
            {'X',"NASDAQ OMX PHLX"},
            {'Y',"BATS Y-Exchange BYX"},
            {'Z',"BATS (Alpha Quote Feed)"},
            {'*',"Composite (Equities)"},
            {'O',"Composite (Options)"},

        };

        /// <summary>
        /// Словарь типов заявок (TIF)
        /// </summary>
        public Dictionary<char, string> DictionaryTif = new Dictionary<char, string>()
        {
            {'D', "DAY"},
            {'G', "GTC"},
            {'X', "GTX"},
            {'F', "FOK"},
            {'I', "IOC"},
            {'O', "OPG"},
            {'E', "EXT"},
            {'1', "OS"},
            {'A', "AEX (auto-x)"},
            {'N', "NOW"}
        };

        /// <summary>
        /// словарь по направляению сделки
        /// </summary>
        public Dictionary<char, string> DictionarySide = new Dictionary<char, string>()
        {
            //
            {'B',"BUY"}, 
            //
            {'C',"BUY TO COVER"},
            {'S',"SELL"},
            {'T',"SSHRT"},
            {'M',"BUY-"},
            {'P',"SELL+"},
            {'E',"SSHRTEX"}
        };


        public List<String> PriceType = new List<string>()
        {
            "Mkt", //Market order
            "MktClo", //Market on close order
            "MktOb", //Market or better
            "MktWow", //Market without waiting
            "Lmt", //Limit
            "LmtClo", //Limit on close
            "LmtStp", //Stop order
            "LmtStpLmt", //Stop limit order
            "LmtOb", //Limit or better
            "Wow", //Without waiting
            "LmtWow", //Limit without waiting
            "Bas", //NYSE basis order
            "Clo", //Close order
            "Pegged", //Peg order
            "SvrStp", //Server side stop order
            "SvrStpLmt", //Server side stop limit order
            "TrailStp", //Trailing stop order
        };


    }
}
